#include "stdio.h"
#include "trap.h"
#include "proc.h"
#include "dbg.h"

#include "lock/spinlock.h"

int
spinlock_isHold(spinlock_t* lk) {
    return lk->locked && lk->cpu == getCurrentCPU();
}

void
spinlock_init(spinlock_t* lk, char* name) {
    lk->locked = 0;
    lk->name = name;
    lk->cpu = NULL;
}

void
spinlock_acquire(spinlock_t* lk) {
    intr_push();
    if (spinlock_isHold(lk)) {
        // TODO panic("already hold the key");
        __DEBUG_INFO(already hold the key);
        return;
    }
    while (__sync_lock_test_and_set(&lk->locked, 1))
        ;

    __sync_synchronize();
    lk->cpu = getCurrentCPU();
}

void
spinlock_release(spinlock_t* lk) {
    if (!spinlock_isHold(lk)) {
        //    panic("do not hold the key");
        __DEBUG_INFO(do not hold the key);
        return;
    }
    __sync_synchronize();

    __sync_lock_release(&lk->locked);
    intr_pop();
}
